package cn.z2huo.knowledge.concurrency.cas.lock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

/**
 * <p>自旋锁
 *
 * @author z2huo
 */
class SpinLock implements Lock {

    /**
     * 锁的持有者
     */
    private final AtomicReference<Thread> owner = new AtomicReference<>();

    @Override
    public void lock() {
        Thread thread = Thread.currentThread();
        // 如果锁被其他线程占用，owner 中值不为 null，cas 操作失败，继续循环
        while (!owner.compareAndSet(null, thread)) {
            // 让出当前剩余的 CPU 时间片
            Thread.yield();
        }
    }

    @Override
    public void unlock() {
        Thread thread = Thread.currentThread();
        // 只有拥有者才能释放锁
        if (thread == owner.get()) {
            // 设置拥有者为空，这里不需要 compareAndSet 操作
            // 因为已经通过 owner 做过线程检查
            owner.set(null);
        }
    }

    @Override
    public void lockInterruptibly() throws InterruptedException {

    }

    @Override
    public boolean tryLock() {
        return false;
    }

    @Override
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
        return false;
    }

    @Override
    public Condition newCondition() {
        return null;
    }
}
